import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.List;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.*;
public class ParcoursCutCorners extends javax.swing.JFrame{

	//(kant waaraan begonnen wordt, 0 = rechts, 1 = links )

	private Side currentside = Side.RECHTS;
	private Dimension Buttonsize;
	private ArrayList<JScalableLabel> list = new ArrayList<JScalableLabel>();
	private ArrayList<JLabel> linelist = new ArrayList<JLabel>();
	private JLayeredPane contentpane = new JLayeredPane();
	private JLayeredPane mainpane = new JLayeredPane();
	private int totalzoom=1;
	private int offset = 10*totalzoom;
	private int currentpane = 0;
	private int drawy = 640+100;
	private int drawx = 400+100;
	private boolean complete = false;
	private Color linecolor = Color.orange;
	private float strokewidth = 6f;
	private float backgroundzoomx=1f*totalzoom*2;
	private float backgroundzoomy=0.8f*totalzoom*2;

	public ParcoursCutCorners(ArrayList<JScalableLabel> argumentlist) {
//		setSize(Math.round(640*totalzoom),Math.round(400*totalzoom));
//		setLocation(0+Math.round((2-totalzoom)*640),0+Math.round(400*(2-totalzoom)));
//		setVisible(true);
		list = argumentlist;
		setContentPane(mainpane);
		BufferedImage bg;
		try {
			bg = ImageIO.read(new File("/home/roel/Afbeeldingen/mindstorms2.jpg"));
			JScalableLabel background = new JScalableLabel(bg,bg,1,1,BarCode.RECHTDOOR,0);
			contentpane.add(background,0,0);
			background.setOpaque(true);
			background.transferFocus();
			background.setScaling(backgroundzoomx, backgroundzoomy);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		mainpane.add(contentpane);
		mainpane.validate();
		contentpane.setVisible(true);
		contentpane.setBounds(Math.round(-320*totalzoom),Math.round(-200*totalzoom),640*2*totalzoom,400*2*totalzoom);
		setLayout(null);
		Insets insets = getInsets();
		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
//		setBackground(Color.WHITE);
		try {
			final BufferedImage bi = ImageIO.read(new File("/home/roel/Afbeeldingen/forward.jpg"));
			Buttonsize = new Dimension(Math.round(bi.getWidth())/2*totalzoom,Math.round(bi.getHeight())/2*totalzoom);

		} catch (IOException e) {
			System.out.println("error");

		}
		drawx = list.get(0).getlabelLocation().x*totalzoom+320*totalzoom;
		drawy = list.get(0).getlabelLocation().y*totalzoom+200*totalzoom;
		for(int i=0; i<list.size();i++) {
			contentpane.add(list.get(i),1,0);
			Point Location = list.get(i).getlabelLocation();
			list.get(i).setOpaque(true);
			System.out.println(list.get(i).getDirection());
			list.get(i).setScaling(0.5f*totalzoom, 0.5f*totalzoom);
			list.get(i).setBounds((Location.x+320)*totalzoom,(Location.y+200)*totalzoom,Buttonsize.height,Buttonsize.width);
			list.get(i).transferFocus();
			repaint();
		}
		for(int i=0;i<5;i++) {
			list.add(list.get(i));
		}
		while(currentpane<list.size()-4){
//			try {
//				Thread.sleep(200);
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
			cutCorners(currentpane-list.size()*(int)Math.floor((float)currentpane/(float)list.size()),false);
			System.out.println("currentpane: " + (currentpane-list.size()*(int)Math.floor((float)currentpane/(float)list.size())) + " of " + list.size()); 
		}

		//		mainpane.validate();
		//		System.out.println(contentpane.getLocation().toString());
		//		for(int j=0; j<100;j++) {
		//			contentpane.setLocation(-j, -j);
		//			try {
		//				Thread.sleep(20);
		//			} catch (InterruptedException e) {
		//				// TODO Auto-generated catch block
		//				e.printStackTrace();
		//			}
		//			System.out.println(j);
		//			contentpane.validate();
		//			repaint();
		//		}



	}

	public static void main(String args[]){
		ParcoursCutCorners tcn = new ParcoursCutCorners(null);
		for(int i=0; i<4; i++){
			tcn.drawRechtdoorLine(Side.RECHTS, Side.RECHTS,2,i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			tcn.drawRechtdoorLine(Side.RECHTS, Side.LINKS, 2,i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			tcn.drawRechtdoorLine(Side.LINKS, Side.LINKS,2, i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			tcn.drawRechtdoorLine(Side.LINKS, Side.RECHTS,2, i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private void cutCorners(int i, boolean fase1) {
		BarCode bc = list.get(i).getBarcode();
		int direction = list.get(i).getDirection();
		switch (bc){
			case RECHTDOOR:
				int totalRechtDoor = 1;
				while(list.get(i+totalRechtDoor).getBarcode()==BarCode.RECHTDOOR) {
					totalRechtDoor++;
				}
				switch(direction) {
					case 1:
						drawx-=Buttonsize.width*(totalRechtDoor-1);
					break;
					case 2: drawx -=Buttonsize.width*(totalRechtDoor-1);
						drawy -=Buttonsize.height*(totalRechtDoor-1);
					break;
					case 3: drawy -=Buttonsize.height*(totalRechtDoor-1);
					break;
				}
				switch(list.get(i+totalRechtDoor).getBarcode()) {
					case RECHTS:
						drawRechtdoorLine(currentside, Side.RECHTS, totalRechtDoor, direction);
						currentside=Side.RECHTS;
					break;
					case LINKS:
						drawRechtdoorLine(currentside, Side.LINKS, totalRechtDoor, direction);
						currentside=Side.LINKS;
					break;
				}
				switch(direction) {
					case 0:
						drawx+=Buttonsize.width*(totalRechtDoor);
					break;
					case 1: drawy +=Buttonsize.height*(totalRechtDoor);
					drawx +=Buttonsize.width*(totalRechtDoor-1);
					break;
					case 2: drawx -=Buttonsize.width*1;
						drawy +=Buttonsize.height*(totalRechtDoor-1);
					break;
					case 3: drawy-=Buttonsize.height;
					break;
				}
				currentpane+=totalRechtDoor;
				System.out.println("rechtdoor: " + totalRechtDoor);
			break;
		case RECHTS:
			switch (list.get(i+1).getBarcode()){
				case LINKS:
				switch(direction) {
					case 1: drawx -=Buttonsize.width;
					break;
					case 2: drawy -=Buttonsize.height;
						drawx -=Buttonsize.width;
					break;
					case 3: drawy -=Buttonsize.height;
					break;
				}
				switch (list.get(i+2).getBarcode()){
					case RECHTS:
						//rechts links rechts
						drawSchuineLine(currentside, Side.RECHTS, direction);
						currentside = Side.RECHTS;
						System.out.println("rechtslinksrechts");
					break;
					default:
						//rechts links links of rechtdoor
						drawSchuineLine(currentside, Side.LINKS, direction);
						currentside = Side.LINKS;
						System.out.println("rechtslinksiets");
					break;
				}
				switch(direction) {
					case 0: drawy+=Buttonsize.height;
						drawx +=Buttonsize.width;
					break;
					case 1: drawy+=Buttonsize.height;
					break;
					case 3: drawx +=Buttonsize.width;
					break;
				}
				currentpane+=2;
			break;
			default:
				//bocht rechts onmiddelijk terug rechts of rechtdoor
				drawCorner(currentside,direction);
				switch(direction) {
					case 0: drawy+=Buttonsize.height;
					break;
					case 1: drawx -=Buttonsize.width;
					break;
					case 2: drawy -=Buttonsize.height;
					break;
					case 3: drawx +=Buttonsize.width;
					break;
				}
				currentpane++;
				System.out.println("rechts");
			break;
			}
		break;
		case LINKS:
			switch (list.get(i+1).getBarcode()){
				case RECHTS:
					switch(direction) {
					case 0: drawy-=Buttonsize.height;
					break;
					case 2: drawx -=Buttonsize.width;
					break;
					case 3: drawx -=Buttonsize.width;
						drawy-=Buttonsize.height;
					break;
					}
					switch (list.get(i+2).getBarcode()){
						case LINKS:
							//links rechts links
							drawSchuineLine(currentside, Side.LINKS, direction);
							currentside = Side.LINKS;
							System.out.println("linksrechtslinks");
						break;
						default:
							//links rechts rechts of rechtdoor
							drawSchuineLine(currentside, Side.RECHTS, direction);
							currentside = Side.RECHTS;
							System.out.println("linksrechtsiets");
						break;
					}
					switch(direction) {
					case 0: drawx+=Buttonsize.height;
						break;
					case 1: drawy +=Buttonsize.width;
					drawx+=Buttonsize.height;
					break;
					case 2: drawy +=Buttonsize.height;
					break;
					}
					currentpane+=2;
				break;

				default:
					//bocht links onmiddelijk terug naar links of rechtdoor
					drawCorner(currentside,direction);
					switch(direction) {
						case 0: drawy-=Buttonsize.height;
						break;
						case 1: drawx +=Buttonsize.width;
						break;
						case 2: drawy +=Buttonsize.height;
						break;
						case 3: drawx -=Buttonsize.width;
						break;
					}
					currentpane++;
					System.out.println("links");
				break;
			}
			break;
		}
	}

	private void drawRechtdoorLine(final Side currentside, final Side nextside, final int duration, final int direction) {

		linelist.add(new JLabel() {


			@Override
			public Dimension getPreferredSize() {
				return super.getPreferredSize();
			}
			@Override
			protected void paintComponent(Graphics g) {
				//afmetingen voor de tekeningen van de schuinelijn zijn:
				Dimension imagedimension = new Dimension(Buttonsize.width*duration,Buttonsize.height);
				int schuin = 0;
				if(currentside != nextside) {
					schuin = 1;
				}
				super.paintComponent(g);
				Graphics2D g2 = (Graphics2D) g;
				g2.setColor(linecolor);
				g2.setStroke(new BasicStroke(strokewidth));
				g2.rotate((90f/180f)*direction*Math.PI,Buttonsize.width*duration/2,Buttonsize.height*duration/2);
				switch(currentside) {
				case LINKS: g2.drawLine(0, offset, imagedimension.width, offset+schuin*(imagedimension.height-2*offset));
				break;
				case RECHTS: g2.drawLine(0, imagedimension.height-offset, imagedimension.width, offset+(1-schuin)*(imagedimension.height-2*offset));
				break;
				}

			}

		});
		Dimension imagedimension = new Dimension(Buttonsize.width*duration,Buttonsize.height*duration);
		int i=linelist.size()-1;
		contentpane.add(linelist.get(i),linelist.size()+2,0);
		linelist.get(i).setBounds(drawx, drawy, imagedimension.width, imagedimension.height);
		linelist.get(i).setVisible(true);
	}
	private void drawSchuineLine(final Side currentside, final Side nextside, final int direction) {

		linelist.add(new JLabel() {
			@Override
			public Dimension getPreferredSize() {
				return super.getPreferredSize();
			}
			@Override
			protected void paintComponent(Graphics g) {
				//afmetingen voor de tekeningen van de schuinelijn zijn:
				Dimension imagedimension = new Dimension(0,0);
				if(currentside == nextside) {
					imagedimension = Buttonsize;
				}
				else {
					imagedimension = new Dimension(Buttonsize.width, offset*2);
				}
				super.paintComponent(g);
				Graphics2D g2 = (Graphics2D) g;
				g2.setColor(linecolor);
				g2.setStroke(new BasicStroke(strokewidth));
				g2.rotate((90f/180f)*direction*Math.PI,Buttonsize.width,Buttonsize.height);
				switch(currentside) {
				case RECHTS: g2.translate(0,Buttonsize.height-offset);
					g2.drawLine(0, 0, imagedimension.width, imagedimension.height);
				break;
				case LINKS: g2.translate(0, Buttonsize.height-(imagedimension.height-offset)); 
					g2.drawLine(0, imagedimension.height, imagedimension.width, 0);
				break;
				}

			}

		});
		Dimension imagedimension = new Dimension(Buttonsize.width*2,Buttonsize.height*2);
		int i=linelist.size()-1;
		contentpane.add(linelist.get(i),linelist.size()+2,0);
		linelist.get(i).setBounds(drawx, drawy, imagedimension.width, imagedimension.height);
		linelist.get(i).setVisible(true);

	}
	private void drawCorner(final Side currentside, final int direction) {
		linelist.add(new JLabel() {
			@Override
			public Dimension getPreferredSize() {
				return super.getPreferredSize();
			}
			@Override
			protected void paintComponent(Graphics g) {
				super.paintComponent(g);
				Graphics2D g2 = (Graphics2D) g;
				g2.setColor(linecolor);
				g2.setStroke(new BasicStroke(strokewidth));
				g2.rotate((90f/180f)*direction*Math.PI,Buttonsize.width/2,Buttonsize.height/2);
				switch(currentside) {
				case RECHTS: g2.drawArc(-offset, Buttonsize.height-offset, offset*2, offset*2, 0, 90);
				break;
				case LINKS: g2.drawArc(-offset, -offset, offset*2, offset*2, -90, 90);
				break;
				}
			}
		});
		int i=linelist.size()-1;
		contentpane.add(linelist.get(i),linelist.size()+2,0);
		linelist.get(i).setBounds(drawx, drawy, Buttonsize.width, Buttonsize.width);
		linelist.get(i).setVisible(true);
	}




}


